package com.fast.modules.acd.service.impl;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import com.fast.common.WebSocketConstant;
import com.fast.modules.acd.entity.Node;
import com.fast.modules.acd.service.QueueService;
import com.fast.modules.acd.service.QueueStorageService;
import com.fast.modules.acd.service.SeatService;
import com.fast.modules.websocket.dto.BaseMessage;
import com.fast.modules.websocket.service.UserService;

/**
 * 队列的服务类
 * @author yaoyuquan
 *
 */
@Service
public class QueueServiceImpl implements QueueService, WebSocketConstant {
	
	@Autowired
	QueueStorageService queueStorageService;
	
	@Autowired
	SeatService seatService;
	
	@Autowired
	UserService userService;
	
	@Autowired
	SimpMessagingTemplate template;
	

	@Override
	public List<Node> status() {
		return queueStorageService.list();
	}

	/**
	 * 用户加入排队的方法
	 * @param node 客户排队的参数，包含客户ID和客户技能列表
	 */
	@Override
	public int join(Node node) {
		
		int size = Integer.MAX_VALUE;
		
		if(node == null) {
			throw new IllegalArgumentException("参数不合法，clientID和skillID不能为空");
		}
		
		Predicate<Node> exists = store -> { return StringUtils.equals(store.getClientID(), node.getClientID()); };
		if(queueStorageService.list().stream().anyMatch(exists)) {
			throw new IllegalArgumentException("当前用户已经在队列中");
		} 
		if(userService.getOnlineRelation().containsKey(node.getClientID())) {
			throw new IllegalArgumentException("当前用户已经在会话中");
		} 
		
		size = queueStorageService.addLast(node);
		
		return size;
	}

	/**
	 * 用户取消排队的方法
	 */
	@Override
	public boolean cancel(String clientID) {
		
		boolean result = false;
		
		if(clientID != null) {
	        Iterator<Node> it = queueStorageService.list().iterator();
	        
	        while(it.hasNext()) {
	        	Node node = it.next();
	        	if(clientID.equals(node.getClientID())) {
	        		queueStorageService.remove(node);
	        		result = true;
	        		break;
	        	}
	        }
		}
		
		return result;
	}

	@Override
	public void notify(int position) throws IOException {
		
		List<Node> list = queueStorageService.list();
		
		for( ; position < queueStorageService.list().size(); position++) {
			Node node = list.get(position);
			BaseMessage message = new BaseMessage();
			message.setContent(++position);
			template.convertAndSend(CLIENT_TOPIC_NAME + "/" + node.getClientID(), message);
		}
		
		
	}

	@Override
	public void push(Node node) {
		queueStorageService.push(node);
	}

	@Override
	public Node pop() {
		return queueStorageService.pop();
	}

}
